/*readme:
这个函数是实现物联网通信的，功能过程，开机后会进入配网阶段，此时，需要电脑连接该设备的wifi,进行一系列配网操作，后续wifi连接成功后，除非重新烧录，不然会重启自动连接wifi

*/
#include<stdio.h>
#include<unistd.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
#include"ohos_init.h"
#include"cmsis_os2.h"
#include"lwip/netifapi.h"
#include"lwip/api_shell.h"
#include "lwip/sockets.h"
#include "wifi_device.h"
#include "wifi_hotspot.h"
#include "wifi_error_code.h"
#include "kv_store.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include <iot_spi.h>
#include "MQTTClient.h"
#include "cJSON.h"
#include <hi_adc.h>
#include <iot_adc.h>
#include "iot_i2c.h"
#include "iot_i2c_ex.h"
#include "iot_errno.h"
#include "iot_uart.h"
#include <DS18B20.h>	
#include "oled.h"//驱动OLED屏幕

//开机时的热点名称及密码
#define AP_SSID "harmony"
#define AP_PSK "20241008"
// #define PEER_TCP_PORT      5555           端口号
// #define CONFIG_SERVER_IP    "192.168.137.1"    IP地址

#define TASK_STACK_SIZE (1024 * 10)
#define TASK_PRIO 25
#define TASK_DELAY_2S 200
#define ONE_SECOND 1
#define DEF_TIMEOUT 15
#define CHANNEL_NUM 3
#define MAC_ADDRESS_LEN 32
#define MAC_DATA0 0
#define MAC_DATA1 1
#define MAC_DATA2 2
#define MAC_DATA3 3
#define MAC_DATA4 4
#define MAC_DATA5 5
#define DHCP_DELAY 100




static int WiFiInit(void);
static void WaitScanResult(void);
static int WaitConnectResult(void);
static void OnWifiScanStateChangedHandler(int state, int size);
static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info);
static void OnHotspotStaJoinHandler(StationInfo *info);
static void OnHotspotStateChangedHandler(int state);
static void OnHotspotStaLeaveHandler(StationInfo *info);

static int g_staScanSuccess = 0;
static int ifWifiConnected = 0;        //wifi连接状态 1 已连接 0未连接
static int g_connectSuccess = 0;
static int g_ssid_count = 0;
static struct netif *g_lwip_netif = NULL;
static int g_apEnableSuccess = 0;
static WifiEvent g_wifiEventHandler = { 0 };
WifiErrorCode error;

const char* KV_SSID = "ssd";
const char* KV_PWD = "pwd";
char SSID_Wifi[50]="";
char PWD_Wifi[50]="";

#define PEER_TCP_PORT      5555
#define CONFIG_SERVER_IP    "192.168.137.1"
#define SELECT_WLAN_PORT "wlan0"
#define SELECT_WIFI_SECURITYTYPE WIFI_SEC_TYPE_PSK


static void saveWifiInfo(void);
static void saveWifi(const char* g_ssid,const char* g_pwd);

static unsigned char sendBuf[1000];
static unsigned char readBuf[1000];

static int WifiConnectAp(const char *ssid, const char *psk, WifiScanInfo *info, int i)
{
    if (strcmp(ssid, info[i].ssid) == 0) {
        int result;
        printf("Select:%3d wireless, Waiting...\r\n", i + 1);

        // 拷贝要连接的热点信息
        WifiDeviceConfig select_ap_config = { 0 };
        strcpy_s(select_ap_config.ssid, sizeof(select_ap_config.ssid), info[i].ssid);
        strcpy_s(select_ap_config.preSharedKey, sizeof(select_ap_config.preSharedKey), psk);
        select_ap_config.securityType = WIFI_SEC_TYPE_PSK;

        if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS) {
            if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1) {
                g_lwip_netif = netifapi_netif_find(SELECT_WLAN_PORT);
                return 0;
            }
        }
    }
    return -1;
}

static int WifiConnect(const char *ssid, const char *psk)
{
    unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT;

    // 初始化WIFI
    if (WiFiInit() != WIFI_SUCCESS) {
        printf("WiFiInit failed, error = %d\r\n", error);
        return -1;
    }
    // 分配空间，保存WiFi信息
    WifiScanInfo *info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT);
    if (info == NULL) {
        return -1;
    }
    // 轮询查找WiFi列表
    do {
        Scan();
        WaitScanResult();
        error = GetScanInfoList(info, &size);
    } while (g_staScanSuccess != 1);
    // 打印WiFi列表
    printf("********************\r\n");
    for (uint8_t i = 0; i < g_ssid_count; i++) {
        printf("no:%03d, ssid:%-30s, rssi:%5d\r\n", i + 1, info[i].ssid, info[i].rssi);
    }
    printf("********************\r\n");
    // 连接指定的WiFi热点
    for (uint8_t i = 0; i < g_ssid_count; i++) {
        if (WifiConnectAp(ssid, psk, info, i) == WIFI_SUCCESS) {
            printf("WiFi connect succeed!\r\n");
            ifWifiConnected =1;
            break;
        }

        if (i == g_ssid_count - 1) {
            printf("ERROR: No wifi as expected\r\n");
            while (1)
                osDelay(DHCP_DELAY);
        }
    }

    // 启动DHCP
    if (g_lwip_netif) {
        dhcp_start(g_lwip_netif);
        printf("begin to dhcp\r\n");
    }
    // 等待DHCP
    for (;;) {
        if (dhcp_is_bound(g_lwip_netif) == ERR_OK) {
            printf("<-- DHCP state:OK -->\r\n");
            // 打印获取到的IP信息
            netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL);
            break;
        }
        osDelay(DHCP_DELAY);
    }

}

static int WiFiInit(void)
{
    g_wifiEventHandler.OnWifiScanStateChanged = OnWifiScanStateChangedHandler;
    g_wifiEventHandler.OnWifiConnectionChanged = OnWifiConnectionChangedHandler;
    g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;
    g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;
    g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;
    error = RegisterWifiEvent(&g_wifiEventHandler);
    if (error != WIFI_SUCCESS) {
        printf("register wifi event fail!\r\n");
        return -1;
    }
    // 使能WIFI
    if (EnableWifi() != WIFI_SUCCESS) {
        printf("EnableWifi failed, error = %d\r\n", error);
        return -1;
    }
    // 判断WIFI是否激活
    if (IsWifiActive() == 0) {
        printf("Wifi station is not active.\r\n");
        return -1;
    }
    return 0;
}

static void WaitScanResult(void)
{
    int scanTimeout = DEF_TIMEOUT;
    while (scanTimeout > 0) {
        sleep(ONE_SECOND);
        scanTimeout--;
        if (g_staScanSuccess == 1) {
            printf("WaitScanResult:wait success[%d]s\n", (DEF_TIMEOUT - scanTimeout));
            break;
        }
    }
    if (scanTimeout <= 0) {
        printf("WaitScanResult:timeout!\n");
    }
}
static void OnWifiScanStateChangedHandler(int state, int size)
{
    (void)state;
    if (size > 0) {
        g_ssid_count = size;
        g_staScanSuccess = 1;
    }
}
static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info)
{
    (void)info;

    if (state > 0) {
        g_connectSuccess = 1;
        printf("callback function for wifi connect\r\n");
    } else {
        printf("connect error,please check password\r\n");
    }
}
static int WaitConnectResult(void)
{
    int ConnectTimeout = DEF_TIMEOUT;
    while (ConnectTimeout > 0) {
        sleep(1);
        ConnectTimeout--;
        if (g_connectSuccess == 1) {
            printf("WaitConnectResult:wait success[%d]s\n", (DEF_TIMEOUT - ConnectTimeout));
            
            break;
        }
    }
    if (ConnectTimeout <= 0) {
        printf("WaitConnectResult:timeout!\n");
        return 0;
    }

    return 1;
}

//wifi的AP模式程序
static int WifiAPTask(void)
{
    // 延时2S便于查看日志
    osDelay(TASK_DELAY_2S);

    // 注册wifi事件的回调函数
    g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;
    g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;
    g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;
    error = RegisterWifiEvent(&g_wifiEventHandler);
    if (error != WIFI_SUCCESS) {
        printf("RegisterWifiEvent failed, error = %d.\r\n", error);
        return -1;
    }
    printf("RegisterWifiEvent succeed!\r\n");
    // 检查热点模式是否使能
    if (IsHotspotActive() == WIFI_HOTSPOT_ACTIVE) {
        printf("Wifi station is  active.\r\n");
        return -1;
    }
    // 设置指定的热点配置
    HotspotConfig config = { 0 };

    strcpy_s(config.ssid, strlen(AP_SSID) + 1, AP_SSID);
    strcpy_s(config.preSharedKey, strlen(AP_PSK) + 1, AP_PSK);
    config.securityType = WIFI_SEC_TYPE_PSK;
    config.band = HOTSPOT_BAND_TYPE_2G;
    config.channelNum = CHANNEL_NUM;

    error = SetHotspotConfig(&config);
    if (error != WIFI_SUCCESS) {
        printf("SetHotspotConfig failed, error = %d.\r\n", error);
        return -1;
    }
    printf("SetHotspotConfig succeed!\r\n");

    // 启动wifi热点模式
    error = EnableHotspot();
    if (error != WIFI_SUCCESS) {
        printf("EnableHotspot failed, error = %d.\r\n", error);
        return -1;
    }
    printf("EnableHotspot succeed!\r\n");

    
    
}
//设备连接加入wiFi触发的回调函数(配置联网WiFi账号和密码在这个函数实现)
static void OnHotspotStaJoinHandler(StationInfo *info)
{
    int index=0;
    if (info == NULL) {
        printf("HotspotStaJoin:info is null.\r\n");
    } else {
        static char macAddress[MAC_ADDRESS_LEN] = { 0 };
        unsigned char *mac = info->macAddress;
        snprintf_s(macAddress, sizeof(macAddress), sizeof(macAddress) - 1, "%02X:%02X:%02X:%02X:%02X:%02X",
            mac[MAC_DATA0], mac[MAC_DATA1], mac[MAC_DATA2], mac[MAC_DATA3], mac[MAC_DATA4], mac[MAC_DATA5]);
        printf("HotspotStaJoin: macAddress=%s, reason=%d.\r\n", macAddress, info->disconnectedReason);
        g_apEnableSuccess++;
    }
    struct sockaddr_in server_sock = {0};
    char recvbuf[1000] = {0};
    int ret = 0;
    unsigned int opt = 1;
    // 创建socket
    int server_fd = socket(AF_INET,SOCK_STREAM,0);
    if (server_fd == -1) {
        printf("tcp_server_task: create socket failed!\r\n");
        return -1;
    } else {
        printf("tcp_server_task: create socket success!\r\n");
    }

    bzero(&server_sock, sizeof(server_sock));
    //设置服务器地址
    server_sock.sin_family = AF_INET;
    server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
    server_sock.sin_port = htons(PEER_TCP_PORT);
    
    //绑定地址
    if (bind(server_fd,(struct sockaddr *)&server_sock,sizeof(struct sockaddr))== -1 )
    {
        printf("ERROR:bind failed\n");
        return -1;
    }
    else{
        printf("bind success\n");
    }
    if(listen(server_fd,5)== -1)
    {
        printf("ERROR:listen failed\n");
        return -1;
    }
    else{
        printf("listen success\n");
    }
    unsigned char buf[100]="hello i'm zhangsan!";
    
        int sin_size = sizeof(struct sockaddr_in);
        int new_fd;
        printf("in while\n");

        if ((new_fd = accept(server_fd, (struct sockaddr*)&server_sock, (socklen_t*)&sin_size)) == -1)
        {
            printf("ERROR:accept failed\n");
            return -1;
        }
        else{
        printf("accept success\r\n");
        }
        while (index < 5)
        {
           if ((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1)
           {
                printf("tcp_server_task:recv failed!\r\n");
                break;
           }
           printf("recv :%s\r\n", recvbuf);

        sleep(1);
        char *ssid_str = strstr(recvbuf,"ssid:");
        char *comma_str = strstr(recvbuf,",pwd:");
        int ret=0;
        if ((ssid_str !=NULL) && (comma_str != NULL))
        {
            char ssid[32]={0};
            char pwd[32]={0};

            memcpy(ssid,ssid_str+5,comma_str-(ssid_str+5));
            memcpy(pwd,comma_str+5,recvbuf+strlen(recvbuf)-(comma_str+5));

            printf("{{{%s,%s}}}\n",ssid,pwd);
            sprintf(buf," ==> %s ++ %d",recvbuf,index++);
            ret =  send(new_fd, buf, strlen(buf) + 1, 0);
            if (ret<0){ 
                printf("TCP server send failed\r\n");
                return -1;
            }
            else{
                printf("TCP server send success\r\n"); 
            }
            saveWifi(ssid,pwd);
            RebootDevice(5);
            
        }else{
            sprintf(buf,"ERROR");
            ret = send(new_fd, buf, strlen(buf) + 1, 0);
            if(ret<0){
                printf("UDP server send failed\r\n");
                return -1;
            }
        }

        if (index >= 5)
        {
            printf("too much error,please retry\r\n");
        }
        }
        closesocket(new_fd);
}
//设备离开wifi触发的回调函数
static void OnHotspotStaLeaveHandler(StationInfo *info)
{
    if (info == NULL) {
        printf("HotspotStaLeave:info is null.\r\n");
    } else {
        static char macAddress[MAC_ADDRESS_LEN] = { 0 };
        unsigned char *mac = info->macAddress;
        snprintf_s(macAddress, sizeof(macAddress), sizeof(macAddress) - 1, "%02X:%02X:%02X:%02X:%02X:%02X",
            mac[MAC_DATA0], mac[MAC_DATA1], mac[MAC_DATA2], mac[MAC_DATA3], mac[MAC_DATA4], mac[MAC_DATA5]);
        printf("HotspotStaLeave: macAddress=%s, reason=%d.\r\n", macAddress, info->disconnectedReason);
        g_apEnableSuccess--;
    }
}
//设备在wifi网络状态改变触发回调函数
static void OnHotspotStateChangedHandler(int state)
{
    printf("HotspotStateChanged:state is %d.\r\n", state);
    if (state == WIFI_HOTSPOT_ACTIVE) {
        printf("wifi hotspot active.\r\n");
    } else {
        printf("wifi hotspot noactive.\r\n");
    }
}
//保存配置的WiFi账号和密码
static void saveWifi(const char* g_ssid,const char* g_pwd)
{   
    
    if (UtilsSetValue(KV_SSID, g_ssid) < 0) {
        printf("setssid failed!\n");
    }
    else{
        printf("set ssd = %s\n", g_ssid);
    }

    if (UtilsSetValue(KV_PWD, g_pwd) < 0) {
        printf("set sid failed!\n");
    }
    else{
        printf("set pwd = %s\n", g_pwd);
    }


}

//连接物联网云平台地址
#define HOST_ADDR "d85a283720.st1.iotda-device.cn-north-4.myhuaweicloud.com"
//连接物联网云客户端ID
#define CLIENT_ID  "65a6274571d845632af87f1a_finalwork_0_0_2024011607"
//连接物联网云设备ID
#define DEVICE_ID "65a6274571d845632af87f1a_finalwork"//填入在物联网平台设置的设备ID
//连接物联网云密码
#define DEVICE_PWD  "d9fb9521018fa15f53df77732d1ed07c15d8934163ba739c5f84dc5bf55cdff3"//填入在物联网平台设置的密码
//连接物联网云设备MQTT的订阅和上报Topic
#define PUBLISH_TOPIC "$oc/devices/"DEVICE_ID"/sys/properties/report"
#define SUBCRIB_TOPIC "$oc/devices/"DEVICE_ID"/sys/commands/#" ///request_id={request_id}"
#define RESPONSE_TOPIC "$oc/devices/"DEVICE_ID"/sys/commands/response" ///request_id={request_id}"
#define SERVICE_ID  "fan_smoke"//设置产品服务ID
//设置设备状态指令
#define OFF     "OFF"
#define ON      "ON"

Network network;
MQTTClient client;

//设备驱动状态

int humi_int_min=0;             //水阀阈值最低值
int humi_int_max=0;             //水阀阈值最高值
int auto_motor = 0;             //是否自动打开水阀的变量
uint32_t Lux_r,Alt_r,Hum_r,P_r,Temp_r;  //直接读取传感器的数据
float Lux,Alt,Hum,P,Temp,soildHumi,currentTemp;   //处理后的数据
float currentTemp_f;            //上一次读数土壤温湿度的数据,这样处理的原因是因为电路问题，可能会出现读数错误
uint32_t soildHumi_min = 290;     //人为设定的湿度最小值
uint32_t soildHumi_int = 120;     //人为设定的湿度范围值
uint32_t soildHumi_min_motor_on = 390;     //人为设定的湿度最小值
uint32_t soildHumi_int_motor_on = 30;     //人为设定的湿度范围值
uint32_t Motor_State=0;          //水阀的状态量
char Lux_Show[8];Hum_Show[5];currentTemp_Show[5];soildHumi_Show[5];Temp_Show[5];  //显示在屏幕上的数值

uint32_t Sleep_time =3;   
uint32_t Motor_flag =0;      //水阀打开的标志位
uint32_t MotorCounite_flag =0;
#define I2C_TASK_STACK_SIZE 1024 * 8
#define I2C_TASK_PRIO 25

//I2C引脚
#define I2C_SDA_GPIO_IDX 13
#define I2C_SCL_GPIO_IDX 14
#define GY39_ADDR 0X5B
//I2C序号
#define WIFI_IOT_I2C_IDX_0 0

#define GPIO_MOTOR 2


static float GetVoltage(void)
{
    unsigned int ret;
    unsigned short data;
    ret = IoTAdcRead(HI_ADC_CHANNEL_3, &data,IOT_ADC_EQU_MODEL_1,HI_ADC_CUR_BAIS_DEFAULT,0);
    if (ret != IOT_SUCCESS) {
        printf("ADC Read Fail\n");
    }
    printf("water data = %d",data);
    int chazhi;
    float baifen;
    if(Motor_State==0){
        chazhi = data -soildHumi_min;
        baifen = (float)chazhi/soildHumi_int;

    }
    else{
        chazhi = data -soildHumi_min_motor_on;
        baifen = (float)chazhi/soildHumi_int_motor_on;
    }
    if(abs((1.0-baifen)*100.0)>=100){
        return 100.00;
    }
    return abs((1.0-baifen)*100.0);
    
}



static void Init_motor(void){
    unsigned int ret;
    ret=IoTGpioInit(GPIO_MOTOR);
    if (ret!=IOT_SUCCESS)
    {
        printf("1Init_motor failed\n");
    }
    ret=IoTGpioSetFunc(GPIO_MOTOR,IOT_GPIO_FUNC_GPIO_12_GPIO);
    if (ret!=IOT_SUCCESS)
    {
        printf("2Init_motor failed\n");
    }

    ret=IoTGpioSetDir(GPIO_MOTOR,IOT_GPIO_DIR_OUT);
        if (ret!=IOT_SUCCESS)
        {
            printf("3Init_motor failed\n");
        }

    IoTGpioSetOutputVal(GPIO_MOTOR,0);

}
static void Set_motor(int value){
    
    unsigned int ret;
    //设置GPIO_MOTOR输出
    if (value ==1)
    {

             ret=IoTGpioSetOutputVal(GPIO_MOTOR,1);
            if (ret!=IOT_SUCCESS)
            {
                printf("Set_motor failed\n");
            }
            Motor_State=1;
            Sleep_time = 1.5;
            MotorCounite_flag=1;
       
    }
    else{

            ret=IoTGpioSetOutputVal(GPIO_MOTOR,0);
        if (ret!=IOT_SUCCESS)
        {
            printf("Set_motor failed\n");
        }
        Motor_State=0;
        Sleep_time = 3;
        MotorCounite_flag==0;
        
    }

}

static void Get_alldata(void){
    uint8_t data[14] = {0};
    uint16_t data_16[2]={0};
    if (IoTI2cRead(WIFI_IOT_I2C_IDX_0, (GY39_ADDR << 1) |0x00, &data, 14) != IOT_SUCCESS) {
        printf("I2C 04 read faild\n");
    }
    Temp_r=(data[4]<<8)|data[5];
    data_16[0]=(((uint16_t)data[6])<<8)|data[7];
    data_16[1]=(((uint16_t)data[8])<<8)|data[9];
    P_r=(((uint32_t)data_16[0])<<16)|data_16[1];
    Hum_r=(data[10]<<8)|data[11];
    Alt_r=((data[12]<<8)|data[13]);

    data_16[0]=(((uint16_t)data[0])<<8)|data[1];
    data_16[1]=(((uint16_t)data[2])<<8)|data[3];
    Lux_r=(((uint32_t)data_16[0])<<16)|data_16[1];
    soildHumi=GetVoltage();
    currentTemp_f = currentTemp;
    currentTemp=DS18B20_Read_Temperature();
    if(Motor_State==1 && (currentTemp<=0 ||  abs(currentTemp-currentTemp_f))>=15 )
    {
        currentTemp=currentTemp_f;
    }
       
    Temp=(float)Temp_r/100;
    P=(float)P_r/100;
    Hum=(float)Hum_r/100;
    Lux=(float)Lux_r/100;

}

static void Auto_openmotor(void){
    if(auto_motor==0)
    {
        return 0;
    }
    else if (auto_motor==1)
    {
        if (soildHumi<=humi_int_min)    
        {
            Motor_State=1;
            Motor_flag=1;
            
        }
        else if (soildHumi > humi_int_max)
        {
            Motor_State=0;
            Motor_flag=0;
            
        }
    }
    
}

static OLED_SHOW(void){
    OLED_Clear(0);
    
        if (ifWifiConnected == 1)
    {
        GUI_ShowString(2, 2, "WiFi connected", 8, 1);
    }
    else
    {
        GUI_ShowString(2,2, "WiFi not connected", 8, 1);
    }
    sprintf(currentTemp_Show, "%.2f", currentTemp);
    
    GUI_ShowString(2, 12, "ST:", 8, 1);
    GUI_ShowString(20, 12, currentTemp_Show,8, 1);
    sprintf(soildHumi_Show, "%.2f", soildHumi);
    GUI_ShowString(2, 22, "SH:", 8, 1);
    GUI_ShowString(20, 22, soildHumi_Show, 8, 1);
    sprintf(Lux_Show, "%.2f", Lux);
    GUI_ShowString(2, 32, "Lux:", 8, 1);
    GUI_ShowString(26, 32, Lux_Show,8, 1);
    sprintf(Temp_Show, "%.2f", Temp);
    GUI_ShowString(2, 42, "AT:", 8, 1);
    GUI_ShowString(20, 42, Temp_Show,8, 1);
    if(Motor_State==1)
    {
        GUI_ShowString(2, 52, "Motor:", 8, 1);
        GUI_ShowString(38, 52,"Running",8, 1);
    }
    if(Motor_State==0)
    {
        GUI_ShowString(2, 52, "Motor:", 8, 1);
        GUI_ShowString(38, 52,"Close",8, 1);
    }
    OLED_Display();
}

static void I2CTask(void)
{

    DS18B20_Init();	
    // Init_motor();
    //初始化io
    IoTGpioInit(I2C_SDA_GPIO_IDX);
    // GPIO_13复用为I2C0_SDA
    IoTGpioSetFunc(I2C_SDA_GPIO_IDX, IOT_GPIO_FUNC_GPIO_13_I2C0_SDA); 
    IoTGpioInit(I2C_SCL_GPIO_IDX);
    // GPIO_14复用为I2C0_SCL
    IoTGpioSetFunc(I2C_SCL_GPIO_IDX, IOT_GPIO_FUNC_GPIO_14_I2C0_SCL); 
    //初始化I2C并设置波特率
    IoTI2cInit(WIFI_IOT_I2C_IDX_0, 4000);
    Init_motor();

    printf("I2C Test Start\n");

    while (1)
    {
        Get_alldata();
        Auto_openmotor();
        Set_motor(Motor_flag);
        OLED_SHOW();
        sleep(Sleep_time);  
    }
}



//接收到控制指令返回上报
static void messageCmdback(char *request_id)
{
    int rc;
    char rsptopic[128]={0};
    sprintf(rsptopic,"%s/request_id=%s",RESPONSE_TOPIC,request_id);
    printf("rsptopic = %s\n",rsptopic);
    MQTTMessage message;
    char payload[300];
    message.qos = 0;
    message.retained = 0;
    message.payload = payload;
    sprintf(payload, "{ \
    \"result_code\": 0, \
    \"response_name\": \"COMMAND_RESPONSE\", \
    \"paras\": { \
        \"result\": \"success\" \
    } \
    }" );
    message.payloadlen = strlen(payload);
    //publish the msg to responese topic
    if ((rc = MQTTPublish(&client, rsptopic, &message)) != 0) {
        printf("Return code from MQTT publish is %d\n", rc);
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
    }
}

//接收到控制指令进行对应处理控制(指令控制在这个函数实现)
static void messageArrived(MessageData* data)
{
    int rc;
    printf("Message arrived on topic %.*s: %.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data,
           data->message->payloadlen, data->message->payload);
   //get request id
    char *request_id_idx=NULL;
    char request_id[60]={0};
    request_id_idx = strstr(data->topicName->lenstring.data,"request_id=");
    strncpy(request_id,request_id_idx+11,36);
    
    //create response topic
    char rsptopic[128]={0};
    sprintf(rsptopic,"%s/request_id=%s",RESPONSE_TOPIC,request_id);

    cJSON *root = cJSON_ParseWithLength( data->message->payload, data->message->payloadlen);
    if(root != NULL){
        cJSON *cmd_name = cJSON_GetObjectItem(root,"command_name");
        if(cmd_name != NULL){
            char *cmd_name_str = cJSON_GetStringValue(cmd_name);
            if(strcmp(cmd_name_str,"switch_motor") == 0){
                cJSON *para_obj = cJSON_GetObjectItem(root,"paras");
                cJSON *status_obj = cJSON_GetObjectItem(para_obj,"motor_state");
                char *data = NULL;
                 data = cJSON_GetStringValue(status_obj);
                 if(data != NULL){
                    if(strcmp(data,OFF)==0)
                    {   
                        // Set_motor(0);
                        Motor_flag=0;
                        auto_motor=0;
                        // buzzer_on();
                        printf("close the motor\n");
                    }
                    else{
                        // buzzer_off();
                        // Set_motor(1);
                        Motor_flag=1;
                        printf("open the motor\n");
                    }
                }
            }else if(strcmp(cmd_name_str,"soid_humi_control") == 0){
                cJSON *para_obj = cJSON_GetObjectItem(root,"paras");
                cJSON *status_obj = cJSON_GetObjectItem(para_obj,"humi_min");
                char *data = NULL;
                int num_value =0;
                num_value = cJSON_GetNumberValue(status_obj);
                 if(num_value != 0){
                    humi_int_min=num_value;
                }
                status_obj = cJSON_GetObjectItem(para_obj,"humi_max");
                num_value = cJSON_GetNumberValue(status_obj);
                 if(num_value != 0){
                    humi_int_max=num_value;
                }
                status_obj = cJSON_GetObjectItem(para_obj,"auto_motor");
                 data = cJSON_GetStringValue(status_obj);
                 if(data != NULL){
                    if(strcmp(data,OFF)==0)
                    {   
                        auto_motor=0;
                        // Set_motor(0);
                        Motor_flag=0;
                    }
                    else{
                        auto_motor=1;
                    }
                }
            }
            messageCmdback(request_id);
        }
        cJSON_Delete(root);
    }
}

//对物联网云平台进行通讯程序(主函数)
static void Mqttc(void)
{
    printf(">> MQTTDemoTask ...\n");

    //wifi连接
    WifiConnect(SSID_Wifi, PWD_Wifi);
    printf("Starting ...\n");
    int rc, count = 0;
    // MQTTClient client;
    int PowLed = 0;
    //进行MQTT连接处理
    NetworkInit(&network);
    printf("NetworkConnect  ...\n");
begin:
    //配置MQTT连接数据
    NetworkConnect(&network, HOST_ADDR, 1883);
    printf("MQTTClientInit  ...\n");
    MQTTClientInit(&client, &network, 2000, sendBuf, sizeof(sendBuf), readBuf, sizeof(readBuf));
    //配置物联网云平台MQTT设备ID
    MQTTString clientId = MQTTString_initializer;
    clientId.cstring = CLIENT_ID; 
    //配置物联网云平台MQTT用户名
    MQTTString userName = MQTTString_initializer;
    userName.cstring = DEVICE_ID; 
    //配置物联网云平台MQTT用户密码
    MQTTString password = MQTTString_initializer;
    password.cstring = DEVICE_PWD; 
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.clientID = clientId;
    data.username = userName;
    data.password = password;
    data.willFlag = 0;
    data.MQTTVersion = 4;
    data.keepAliveInterval = 60;
    data.cleansession = 1;
    //连接物联网云平台
    // printf("MQTTConnect  ...\n");
    rc = MQTTConnect(&client, &data);
    if (rc != 0) {
        // printf("MQTTConnect: %d\n", rc);
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
        osDelay(200);
        goto begin;
    }
  
    //配置物联网云平台MQTT订阅对应指令Topic
    printf("MQTTSubscribe  ...\n");
    rc = MQTTSubscribe(&client, SUBCRIB_TOPIC, 0, messageArrived);
    if (rc != 0) {
        // printf("MQTTSubscribe: %d\n", rc);
        osDelay(200);
        goto begin;
    }
  
    //循环向物联网云平台发送传感器数据
    while (1) {
        MQTTMessage message;
        // char *publishtopic="$oc/devices/test_fan_1/sys/properties/report";
        char payload[1000]={0};
        cJSON *root = cJSON_CreateObject();
        if(root != NULL){
            cJSON *serv_arr = cJSON_AddArrayToObject(root, "services");
            cJSON *arr_item =  cJSON_CreateObject();
            cJSON_AddStringToObject(arr_item,"service_id",SERVICE_ID);
            cJSON *pro_obj = cJSON_CreateObject();
            cJSON_AddItemToObject(arr_item,"properties",pro_obj);
            cJSON_AddNumberToObject(pro_obj,"temp",Temp);
            cJSON_AddNumberToObject(pro_obj,"soild_humi",soildHumi);
            cJSON_AddNumberToObject(pro_obj,"air_humi",Hum);
            cJSON_AddNumberToObject(pro_obj,"air_pressure",P);
            cJSON_AddNumberToObject(pro_obj,"lux",Lux);
            cJSON_AddNumberToObject(pro_obj,"soild_temp",currentTemp);
            cJSON_AddNumberToObject(pro_obj,"motor_state",Motor_State);
            cJSON_AddItemToArray(serv_arr,arr_item);
            char *palyload_str = cJSON_PrintUnformatted(root);
            strcpy(payload,palyload_str);
            cJSON_free(palyload_str);
            cJSON_Delete(root);
        }
        message.qos = 0;
        message.retained = 0;
        message.payload = payload;
        message.payloadlen = strlen(payload);
        if ((rc = MQTTPublish(&client, PUBLISH_TOPIC, &message)) != 0) {
            // printf("Return code from MQTT publish is %d\n", rc);
            NetworkDisconnect(&network);
            MQTTDisconnect(&client);
            goto begin;
        }else{
            // printf("mqtt publish success:%s\n",payload);
        }
        MQTTYield(&client,Sleep_time*1000);
    }
}    

static void Final_app(void)
{
    int notfound = 0;
    oled_gpio_io_init();
    IotSpiCfgInitParam init_param={
        .isSlave = 0
    };
    screen_spi_master_init(0); 
    OLED_Init();
    Init_motor();
    osThreadAttr_t attr;
    attr.name = "Final_appTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = TASK_STACK_SIZE;
    attr.priority = 25;
    
    if(UtilsGetValue(KV_SSID,SSID_Wifi,sizeof(SSID_Wifi)-1)<0){
        printf("get ssid failed\n");
        notfound = 1;
    }
    printf("key : %s ,value : %s    \n",KV_SSID,SSID_Wifi);

    if(UtilsGetValue(KV_PWD,PWD_Wifi,sizeof(PWD_Wifi)-1)<0){
        printf("get pwd failed\n");
        notfound = 1;
    }
    printf("key : %s ,value : %s    \n",KV_PWD,PWD_Wifi);

    printf(" notfound value is %d \n",notfound);
    
    osThreadAttr_t attr1;
    attr1.name = "OLED_task";
    attr1.attr_bits = 0U;
    attr1.cb_mem = NULL;
    attr1.cb_size = 0U;
    attr1.stack_mem = NULL;
    attr1.stack_size = 4096;
    attr1.priority = 20;
    
    if (notfound == 1)           
    {   
            OLED_Clear(0);
            GUI_ShowString(2, 10, "Please use the TCP ", 8, 1);
            GUI_ShowString(2, 20, "send wifi message ", 8, 1);
            GUI_ShowString(2, 30, "ssid:{..},pwd:{..} ", 8, 1);
            GUI_ShowString(2, 40, "Hotspot:harmony ", 8, 1);
            GUI_ShowString(50, 50, "20241008 ", 8, 1);
            OLED_Display();
       if (osThreadNew((osThreadFunc_t)WifiAPTask,NULL,&attr)==NULL)
       {
        printf("Failed to create WifiAPTask!\r\n");
       }
       else{
        printf("Successd to create WifiAPTask!\r\n");
       }
    }
    else{
        if (osThreadNew((osThreadFunc_t)Mqttc,NULL,&attr)==NULL)
        {
            printf("Failed to create WifiSTATask!\r\n");
        }
        else{
            printf("Successd to create WifiSTATask!\r\n");
        }
        if (osThreadNew((osThreadFunc_t)I2CTask, NULL, &attr1) == NULL) {
        printf("Failed to create OLED_task!\n");
        }
    }
}
APP_FEATURE_INIT(Final_app);